/* 
 * File: timespanstablemodel.h
 * Project: QTimeTracker
 * Author: Steve Sindelar, http://stevesindelar.cz
 * Licence: NewBSD licence.
 */

#ifndef TIMESPANSTABLEMODEL_H
#define TIMESPANSTABLEMODEL_H

#include "../QTimeTracker.Core/timespan.h"
#include "../QTimeTracker.Core/timespandata.h"
#include "../QTimeTracker.Core/xmlpersister.h"
#include "../QTimeTracker.Core/item.h"
#include "abstracttablemodel.h"

using namespace Core;

namespace Ui
{

	/**
	 * Model of list of TimeSpans which belong to given \ref Core::Item "Item".
	 */
	class TimeSpansTableModel : public AbstractTableModel 
	{
		Q_OBJECT

	public:
		TimeSpansTableModel()
		{
			this->item = NULL;
			this->addColumn(new FromColumn(this));
			this->addColumn(new ToColumn(this));
			this->addColumn(new LengthColumn(this));
			this->addColumn(new NoteColumn(this));
		}

		inline int rowCount(const QModelIndex & parent = QModelIndex()) const
		{
			if (this->item == NULL) 
			{
				return 0;
			}
			else 
			{
				return this->item->timeSpans.size();
			}
		}

		/**
		 * Sets the \ref Core::Item "Item" whose time spans will be shown in table.
		 */
		inline void setData(Item* item)
		{
			this->item = item;
			emit this->layoutChanged();
		}

		/**
		 * Updates columns that should be updated after every tick when running. (Length and To).
		 */
		inline void timerTick()
		{
			emit this->layoutChanged();
		}

	private:
		Item* item;
		QList<TimeSpan> emptyData;
		/**
		 * Helper method: convention for data access.
		 */
		inline QList<TimeSpan>& getSpans() 
		{ 
			if (this->item == NULL)
			{
				return this->emptyData;
			}
			else
			{
				return this->item->timeSpans; 
			}
		}


		/** 
		 * @name Columns classes
		 * These classes represent columns in the table. 
		 * They are responsible for providing data of column, header, ...
		 */
		//@{

		class FromColumn : public TableModelColumn
		{
		public:
			FromColumn(TimeSpansTableModel* model);

			QString getHeader() const;
			QVariant getDataForEditRole(const QModelIndex &index) const;
			QVariant getDataForDisplayRole(const QModelIndex &index) const;
			bool setData(const QModelIndex &index, const QVariant &value) const;
			Qt::ItemFlags getFlags( const QModelIndex & index) const;
		private:
			TimeSpansTableModel* model;
		};

		class ToColumn : public TableModelColumn
		{
		public:
			ToColumn(TimeSpansTableModel* model);

			QString getHeader() const;
			QVariant getDataForEditRole(const QModelIndex &index) const;
			QVariant getDataForDisplayRole(const QModelIndex &index) const;
			bool setData(const QModelIndex &index, const QVariant &value) const;
			Qt::ItemFlags getFlags( const QModelIndex & index) const;
		private:
			TimeSpansTableModel* model;
		};

		class LengthColumn : public TableModelColumn
		{
		public:
			LengthColumn(TimeSpansTableModel* model);

			QString getHeader() const;
			QVariant getDataForEditRole(const QModelIndex &index) const;
			QVariant getDataForDisplayRole(const QModelIndex &index) const;
			bool setData(const QModelIndex &index, const QVariant &value) const;
			Qt::ItemFlags getFlags( const QModelIndex & index) const;
		private:
			TimeSpansTableModel* model;
		};

		class NoteColumn : public TableModelColumn
		{
		public:
			NoteColumn(TimeSpansTableModel* model);

			QString getHeader() const;
			QVariant getDataForEditRole(const QModelIndex &index) const;
			QVariant getDataForDisplayRole(const QModelIndex &index) const;
			bool setData(const QModelIndex &index, const QVariant &value) const;
			Qt::ItemFlags getFlags( const QModelIndex & index) const;
		private:
			TimeSpansTableModel* model;
		};

		//@}
	};

} //namespace

#endif //TIMESPANSTABLEMODEL_H
